#include <iostream>
#include <pthread.h>
#include <string.h>
#include <cstdio>
#include <cstdlib>
#include <cassert>
using namespace std;
//模仿c++的多线程，对多线程进行封装
/*
    Thread thrad(new Thread(func(),(void*)"string",1))

*/
class Thread;
//用一个结构体去当作pthread_create的第四个参数
class Context{
public:
    Thread *this_;
    void* args_;
public:
    Context():this_(nullptr),args_(nullptr)
    {
        
    }
    ~Context()
    {}
};



class Thread{
public:
    const int num =1024;
    //using func_t = function<void*(void*)>;   //包装器，把void*(void*)的函数指针包装成func_t
    typedef function<void*(void*)> func_t;
public:
//构造函数
    Thread(func_t func,void* args=nullptr, int number=0)
    :func_(func)
    ,args_(args)
    {
        char buffer[num];
        snprintf(buffer,sizeof buffer,"thread-%d",number);
        name_ = buffer;
        Context* ctx = new Context();
        ctx->this_ = this;
        ctx->args_ = args_;
        int n = pthread_create(&tid_,nullptr,static_routine,ctx);
        assert(n==0);  //在意料之中的错误使用assert，在release（会对代码进行一些优化）的版本下，assert不执行
        //异常 ==if  意料之外用异常或者if判断
        (void)n;
    }
    //在类内创建，想让线程执行对应的方法，需要将方法设置为static
    static void* static_routine(void* args)   
    //非静态成员的话，类内第一个参数是this指针，这里会报错因为对应pthread_create的函数指针只允许有一个参数
    //静态方法不能调用成员成员函数和成员变量
    {
        //需要对ctx进行强转
        Context* ctx = static_cast<Context*>(args);
        void* ret = ctx->this_->run(ctx->args_);
        delete ctx;
        return ret;
    }

    void join()
    {
        int n = pthread_join(tid_,nullptr);
        assert(n==0);
        (void)n;
    }

    void* run(void* args)
    {
        return func_(args);
    }
    ~Thread()
    {}


private:
    string name_; 
    func_t func_;
    void* args_;
    

    pthread_t tid_;
};




//
